package controller;

import bean.Category;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializer;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import service.CategoryService;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.time.LocalDateTime;

@WebServlet(urlPatterns = {
        "/categories",
        "/categories/detail",
        "/categories/with-count",
        "/categories/create",
        "/categories/update",
        "/categories/delete",
        "/categories/exists"
})
public class CategoryController extends HttpServlet {
    private final CategoryService categoryService = new CategoryService();
    private final Gson gson = new GsonBuilder()
            .registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (src, typeOfSrc, context) -> {
                if (src == null) return null;
                return new JsonPrimitive(src.toString().replace('T', ' '));
            })
            .create();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=UTF-8");
        String uri = req.getRequestURI();
        Integer userId = parseIntOrNull(req.getParameter("userId"));
        if (userId == null) userId = 1; // 简化：默认用户ID 1

        if (uri.endsWith("/categories")) {
            List<Category> list = categoryService.listByUserId(userId);
            resp.getWriter().write(gson.toJson(list));
        } else if (uri.endsWith("/detail")) {
            Integer id = parseIntOrNull(req.getParameter("id"));
            Category c = id == null ? null : categoryService.getById(id);
            if (c == null) {
                resp.getWriter().write("{\"success\":false,\"error\":\"not_found\"}");
            } else {
                resp.getWriter().write(gson.toJson(c));
            }
        } else if (uri.endsWith("/with-count")) {
            List<Map<String, Object>> list = categoryService.categoriesWithNoteCount(userId);
            resp.getWriter().write(gson.toJson(list));
        } else if (uri.endsWith("/exists")) {
            String name = req.getParameter("name");
            Integer excludeId = parseIntOrNull(req.getParameter("excludeId"));
            boolean exists = categoryService.existsByName(userId, name, excludeId);
            resp.getWriter().write(String.format(Locale.ROOT, "{\"exists\":%s}", exists));
        } else {
            resp.getWriter().write("{\"success\":false,\"error\":\"unsupported_route\"}");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=UTF-8");
        String uri = req.getRequestURI();
        Integer userId = parseIntOrNull(req.getParameter("userId"));
        if (userId == null) userId = 1;

        if (uri.endsWith("/create")) {
            Category c = new Category();
            c.setName(req.getParameter("name"));
            c.setDiscription(req.getParameter("discription"));
            c.setUserId(userId);
            int r = categoryService.add(c);
            resp.getWriter().write(String.format(Locale.ROOT, "{\"success\":%s}", r > 0));
        } else if (uri.endsWith("/update")) {
            Category c = new Category();
            c.setId(parseIntOrNull(req.getParameter("id")));
            c.setName(req.getParameter("name"));
            c.setDiscription(req.getParameter("discription"));
            c.setUserId(userId);
            int r = categoryService.update(c);
            resp.getWriter().write(String.format(Locale.ROOT, "{\"success\":%s}", r > 0));
        } else if (uri.endsWith("/delete")) {
            Integer id = parseIntOrNull(req.getParameter("id"));
            int r = id == null ? 0 : categoryService.delete(id, userId);
            resp.getWriter().write(String.format(Locale.ROOT, "{\"success\":%s}", r > 0));
        } else {
            resp.getWriter().write("{\"success\":false,\"error\":\"unsupported_route\"}");
        }
    }

    private Integer parseIntOrNull(String v) {
        try { return v == null || v.isBlank() ? null : Integer.valueOf(v); } catch (Exception ignored) { return null; }
    }
}